<template>
  <el-card class="card-box">
    <div class="header">
      <h2>维修过程管理</h2>
      <div class="stats">
        <el-tag type="danger">待处理: {{ stats.pending }}</el-tag>
        <el-tag type="success">已完成: {{ stats.completed }}</el-tag>
      </div>
    </div>

    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
      <el-tab-pane label="记录维修" name="record">
        <div class="form-wrapper">
          <el-form 
            :model="processForm" 
            label-width="120px" 
            :rules="rules"
            ref="processFormRef"
            label-position="top"
          >
            <!-- 维修单选择 -->
            <el-form-item label="维修单信息" prop="repairRequestId">
              <div class="request-selector">
                <el-button 
                  type="primary" 
                  plain
                  @click="showRequestDialog"
                  style="margin-right: 10px"
                >
                  <el-icon><Search /></el-icon> 选择维修单
                </el-button>
                
                <div v-if="selectedRequest" class="request-info-display">
                  <div class="request-info-row">
                    <span class="info-label">维修单号:</span>
                    <span class="info-value">{{ selectedRequest.id }}</span>
                  </div>
                  <div class="request-info-row">
                    <span class="info-label">设备ID:</span>
                    <span class="info-value">{{ selectedRequest.serialNumber }}</span>
                  </div>
                  <div class="request-info-row">
                    <span class="info-label">维修人员ID:</span>
                    <span class="info-value">{{ selectedRequest.assignedToId }}</span>
                  </div>
                  <div class="request-info-row full-width">
                    <span class="info-label">故障描述:</span>
                    <span class="info-value multiline">{{ selectedRequest.faultDescription }}</span>
                  </div>
                </div>
              </div>
            </el-form-item>

            <!-- 维修时段 -->
            <el-form-item label="维修时段" required>
              <el-date-picker
                v-model="timeRange"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                value-format="YYYY-MM-DD HH:mm:ss"
              />
            </el-form-item>

            <!-- 维修说明 -->
            <el-form-item label="维修说明" prop="repairNotes">
              <el-input
                v-model="processForm.repairNotes"
                type="textarea"
                :rows="4"
                placeholder="请详细描述维修过程和发现的问题"
                show-word-limit
                maxlength="500"
              />
            </el-form-item>

            <!-- 总费用 -->
            <el-form-item label="总费用 (元)" prop="totalCost">
              <el-input-number
                v-model="processForm.totalCost"
                :min="0"
                :precision="2"
                :controls="false"
                placeholder="请输入总费用"
              />
            </el-form-item>

            <!-- 维修凭证 -->
            <el-form-item label="维修凭证">
              <el-upload
                v-model:file-list="fileList"
                :limit="3"
                :auto-upload="false"
                :accept="fileAcceptTypes"
                :on-exceed="handleFileExceed"
              >
                <el-button type="primary">
                  <el-icon><Upload /></el-icon>选择文件
                </el-button>
                <template #tip>
                  <div class="el-upload__tip">
                    支持上传图片、PDF或Word文档（最多3个文件）
                    <div v-if="fileList.length > 0" class="file-preview-wrapper">
      <a
        :href="getFileUrl(fileList[0])"
        target="_blank"
        class="file-preview"
        @click.stop
      >
        <img
          v-if="isImage(fileList[0])"
          :src="getFileUrl(fileList[0])"
          class="preview-img"
          alt="预览"
        />
        <span v-else class="file-name">{{ fileList[0].name }}</span>

        <!-- 悬浮放大框在左侧显示 -->
        <div class="file-hover-preview left-preview">
          <img
            v-if="isImage(fileList[0])"
            :src="getFileUrl(fileList[0])"
            class="zoom-img"
            alt="大图预览"
          />
          <span v-else class="zoom-text">{{ fileList[0].name }}</span>
        </div>
      </a>
    </div>
                  </div>
                </template>
              </el-upload>
            </el-form-item>

            <!-- 配件列表 -->
            <el-divider>
              <span style="font-size: 16px; font-weight: 500;">
                <el-icon><Box /></el-icon> 使用配件
              </span>
              <el-button 
                type="primary" 
                size="small" 
                plain 
                @click="addPart"
              >
                <el-icon><Plus /></el-icon>添加配件
              </el-button>
            </el-divider>

            <div class="parts-container">
              <el-card 
                v-for="(part, index) in processForm.parts" 
                :key="index" 
                shadow="hover"
                class="part-card"
              >
                <div class="part-header">
                  <span class="part-title">
                    <el-icon><Goods /></el-icon> 配件 #{{ index + 1 }}
                  </span>
                  <el-button 
                    type="danger" 
                    size="small" 
                    text 
                    @click="removePart(index)"
                  >
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
                
                <el-form-item
                  label="配件名称"
                  :prop="`parts.${index}.partName`"
                  :rules="{ required: true, message: '请输入配件名称', trigger: 'blur' }"
                >
                  <el-input 
                    v-model="part.partName" 
                    placeholder="如：轴承、电路板等" 
                  />
                </el-form-item>

                <div class="part-details">
                  <el-form-item
                    label="数量"
                    :prop="`parts.${index}.quantity`"
                    :rules="{ required: true, message: '请输入数量', trigger: 'blur' }"
                  >
                    <el-input-number
                      v-model="part.quantity"
                      :min="1"
                      :controls="false"
                    />
                  </el-form-item>

                  <el-form-item
                    label="单价(元)"
                    :prop="`parts.${index}.unitPrice`"
                    :rules="{ required: true, message: '请输入单价', trigger: 'blur' }"
                  >
                    <el-input-number
                      v-model="part.unitPrice"
                      :min="0"
                      :precision="2"
                      :controls="false"
                    />
                  </el-form-item>
                </div>

                <el-form-item label="配件凭证">
                  <el-upload
                    v-model:file-list="part.fileList"
                    :limit="1"
                    :auto-upload="false"
                    :accept="fileAcceptTypes"
                    :on-exceed="() => ElMessage.warning('只能上传一个文件')"
                  >
                    <el-button type="primary" plain size="small">
                      <el-icon><Upload /></el-icon>上传凭证
                    </el-button>
                    <template #tip>
                      <div class="el-upload__tip">
                        <div v-if="part.fileList.length > 0" class="file-preview">
                          <el-icon><Document /></el-icon>
                          <span>{{ part.fileList[0].name }}</span>
                        </div>
                        <span v-else>支持图片或PDF文件</span>
                      </div>
                    </template>
                  </el-upload>
                </el-form-item>
              </el-card>
            </div>

            <!-- 表单操作 -->
            <el-form-item class="form-actions">
              <el-button 
                type="primary" 
                @click="submitProcess"
                :loading="isSubmitting"
              >
                <el-icon v-if="!isSubmitting"><Check /></el-icon>
                {{ isSubmitting ? '提交中...' : '提交记录' }}
              </el-button>
              <el-button @click="resetForm">
                <el-icon><Refresh /></el-icon>重置表单
              </el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-tab-pane>

      <el-tab-pane label="维修记录" name="history">
        <el-form inline class="filter-bar">
          <el-form-item label="维修单号:">
            <el-input-number
              v-model="searchParams.repairRequestId"
              placeholder="维修单号"
              :controls="false"
              clearable
            />
          </el-form-item>
          <el-form-item label="维修人员ID:">
            <el-input-number
              v-model="searchParams.repairerId"
              placeholder="维修人员ID"
              :controls="false"
              clearable
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="loadProcessRecords">
              <el-icon><Search /></el-icon>搜索
            </el-button>
            <el-button @click="resetSearch">
              <el-icon><Refresh /></el-icon>重置
            </el-button>
          </el-form-item>
        </el-form>

        <div class="responsive-table-container">
          <table class="custom-table">
            <thead>
              <tr>
                <th>编号</th>
                <th>维修单号</th>
                <th>维修人员</th>
                <th>维修时段</th>
                <th>总费用</th>
                <th>维修凭证</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="item in processRecords" :key="item.id">
                <td>{{ item.id }}</td>
                <td>{{ item.repairRequestId }}</td>
                <td>{{ item.repairerId }}</td>
                <td>{{ formatTimeRange(item.startTime, item.endTime) }}</td>
                <td>¥{{ item.totalCost?.toFixed(2) || '0.00' }}</td>
                <td>
  <template v-if="item.repairFileUrl">
    <template v-if="isImageFile(item.repairFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="item.repairFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(item.repairFileUrl)"
          />
        </template>
        <img :src="item.repairFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="item.repairFileUrl"
        :download="item.repairFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(item.repairFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
                <td>
                  <div class="action-btns">
                    <el-button
                      :icon="View"
                      circle
                      plain
                      size="small"
                      type="info"
                      @click="showDetail(item)"
                    />
                  </div>
                </td>
              </tr>
              <tr v-if="processRecords.length === 0">
                <td colspan="7" class="text-center py-4">
                  <el-empty description="暂无维修记录" />
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="pagination-container">
          <el-pagination
            v-model:current-page="pagination.current"
            v-model:page-size="pagination.size"
            :page-sizes="[5, 10, 20]"
            layout="total, sizes, prev, pager, next, jumper"
            background
            :total="pagination.total"
            @size-change="loadProcessRecords"
            @current-change="loadProcessRecords"
          />
        </div>
      </el-tab-pane>
    </el-tabs>

    <!-- 维修记录详情对话框 -->
    <el-dialog 
      v-model="detailDialog.visible" 
      :title="`维修记录详情 #${currentRecord?.id}`" 
      width="800px"
    >
      <div v-if="currentRecord" class="detail-content">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="维修单号">
            {{ currentRecord.repairRequestId }}
          </el-descriptions-item>
          <el-descriptions-item label="维修人员ID">
            {{ currentRecord.repairerId }}
          </el-descriptions-item>
          <el-descriptions-item label="开始时间">
            {{ formatDateTime(currentRecord.startTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="结束时间">
            {{ formatDateTime(currentRecord.endTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="总费用">
            ¥{{ currentRecord.totalCost?.toFixed(2) || '0.00' }}
          </el-descriptions-item>
        </el-descriptions>

        <el-divider>
          <el-icon><Notebook /></el-icon> 维修说明
        </el-divider>
        <div class="repair-notes">{{ currentRecord.repairNotes }}</div>

        <el-divider>
          <el-icon><Folder /></el-icon> 维修凭证
        </el-divider>
        <td>
  <template v-if="currentRecord.repairFileUrl">
    <template v-if="isImageFile(currentRecord.repairFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="currentRecord.repairFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(currentRecord.repairFileUrl)"
          />
        </template>
        <img :src="currentRecord.repairFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="currentRecord.repairFileUrl"
        :download="currentRecord.repairFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(currentRecord.repairFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>

        <el-divider>
          <el-icon><Box /></el-icon> 使用配件
        </el-divider>
        <table class="custom-table">
          <thead>
            <tr>
              <th>配件名称</th>
              <th>数量</th>
              <th>单价</th>
              <th>总价</th>
              <th>凭证</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in currentParts" :key="item.id">
              <td>{{ item.partName }}</td>
              <td>{{ item.quantity }}</td>
              <td>¥{{ item.unitPrice?.toFixed(2) || '0.00' }}</td>
              <td>¥{{ (item.quantity * item.unitPrice)?.toFixed(2) || '0.00' }}</td>
              <td>
  <template v-if="item.partFileUrl">
    <template v-if="isImageFile(item.partFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="item.partFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(item.partFileUrl)"
          />
        </template>
        <img :src="item.partFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="item.partFileUrl"
        :download="item.partFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(item.partFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
            </tr>
          </tbody>
        </table>
      </div>
    </el-dialog>

    <!-- 维修申请选择对话框 -->
    <el-dialog v-model="requestDialog.visible" title="选择维修申请" width="80%">
      <div class="content-wrapper">
        <div class="filter-area">
          <el-form inline>
            <el-form-item label="设备ID:">
              <el-select
                v-model="requestSearchParams.serialNumber"
                filterable remote clearable reserve-keyword
                placeholder="请输入设备ID"
                :remote-method="fetchSerialSuggestions"
                :loading="loadingSerialNumbers"
              >
                <el-option
                  v-for="item in serialNumberOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="申请人ID:">
              <el-input-number
                v-model="requestSearchParams.applicantId"
                placeholder="申请人ID"
                :controls="false"
                clearable
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="loadAssignedRequests">
                <el-icon><Search /></el-icon>搜索
              </el-button>
              <el-button @click="resetRequestSearch">
                <el-icon><Refresh /></el-icon>重置
              </el-button>
            </el-form-item>
          </el-form>
        </div>

        <div class="responsive-table-container">
          <table class="custom-table">
            <thead>
              <tr>
                <th>ID</th>
                <th>设备ID</th>
                <th>申请人ID</th>
                <th>故障描述</th>
                <th>附件</th>
                <th>申请时间</th>
                <th>维修人员ID</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="item in assignedRequests" :key="item.id">
                <td>{{ item.id }}</td>
                <td>{{ item.serialNumber }}</td>
                <td>{{ item.applicantId }}</td>
                <td class="truncate">{{ item.faultDescription }}</td>
                <td>
                  <el-button
                    v-if="item.faultImageUrl"
                    type="primary"
                    link
                    @click="downloadFile(item.faultImageUrl)"
                  >
                    下载
                  </el-button>
                  <span v-else class="no-attachment">无附件</span>
                </td>
                <td>{{ formatDateTime(item.requestTime) }}</td>
                <td>{{ item.assignedToId }}</td>
                <td>
                  <div class="action-btns">
                    <el-button
                      type="primary"
                      size="small"
                      @click="handleRequestSelect(item)"
                    >
                      <el-icon><Select /></el-icon>
                    </el-button>
                  </div>
                </td>
              </tr>
              <tr v-if="assignedRequests.length === 0">
                <td colspan="8" class="text-center py-4">
                  <el-empty description="暂无维修申请" />
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="pagination-container">
          <el-pagination
            v-model:current-page="requestPagination.current"
            v-model:page-size="requestPagination.size"
            :total="requestPagination.total"
            :page-sizes="[5, 10, 20]"
            layout="total, sizes, prev, pager, next, jumper"
            background
            @size-change="loadAssignedRequests"
            @current-change="loadAssignedRequests"
          />
        </div>
      </div>
    </el-dialog>
  </el-card>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { 
  Document, Delete, Plus, Upload, Search, Check, Refresh,
 Goods, Box, View,  Notebook, Folder, Select
} from '@element-plus/icons-vue'
import { ElMessage} from 'element-plus'
import request from '@/utils/request'
import { Download } from '@element-plus/icons-vue'; // 导入 Download 图标组件
// 类型定义
interface RepairRequest {
  id: number
  serialNumber: string
  applicantId: number
  faultDescription: string
  faultImageUrl: string
  requestTime: string
  status: string
  assignedToId: number
  assignTime: string
  updateTime: string
  deleted: number
}

interface RepairProcess {
  id: number
  repairRequestId: number
  repairerId: number
  startTime: string
  endTime: string
  repairNotes: string
  repairFileUrl: string
  totalCost: number
  createTime: string
}

interface RepairPart {
  id: number
  repairProcessId: number
  partName: string
  quantity: number
  unitPrice: number
  totalPrice: number
  partFileUrl: string
  status: string
  approvalNotes: string
  approvalTime: string
}

// 组件状态
const activeTab = ref('record')
const selectedRequest = ref<RepairRequest | null>(null)
const isSubmitting = ref(false)

const processForm = reactive({
  repairRequestId: null as number | null,
  repairerId: null as number | null,
  repairNotes: '',
  totalCost: 0,
  repairFileUrl: '',
  parts: [] as Array<{
    partName: string
    quantity: number
    unitPrice: number
    fileList: any[]
  }>
})

const timeRange = ref<string[]>([])
const fileList = ref<any[]>([])
const processFormRef = ref()

const assignedRequests = ref<RepairRequest[]>([])
const processRecords = ref<RepairProcess[]>([])
const currentRecord = ref<RepairProcess | null>(null)
const currentParts = ref<RepairPart[]>([])

const searchParams = reactive({
  repairRequestId: null as number | null,
  repairerId: null as number | null
})

const requestSearchParams = reactive({
  serialNumber: null as string | null,
  applicantId: null as number | null,
  status: '已分配'
})

const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
})

const requestPagination = reactive({
  current: 1,
  size: 10,
  total: 0
})

const stats = reactive({
  pending: 0,
  completed: 0
})

const detailDialog = reactive({
  visible: false
})

const requestDialog = reactive({
  visible: false
})

const fileAcceptTypes = 'image/*,.pdf,.doc,.docx'

// 表单验证规则
const rules = {
  repairRequestId: [
    { required: true, message: '请选择维修单', trigger: 'blur' }
  ],
  repairNotes: [
    { required: true, message: '请输入维修说明', trigger: 'blur' }
  ],
  totalCost: [
    { required: true, message: '请输入总费用', trigger: 'blur' }
  ]
}


const handleTabChange= ()=>{

}
// 生命周期钩子
onMounted(() => {
  loadAssignedRequests()
  loadProcessRecords()
})

// 方法
const loadAssignedRequests = async () => {
  try {

    const params: {
      page: number;
      size: number;
      [key: string]: any; // ✨ 关键的索引签名：允许动态访问键，值为 any 类型
    } = {
      page: requestPagination.current, // 从 requestPagination 获取当前页码
      size: requestPagination.size,   // 从 requestPagination 获取每页大小
      ...requestSearchParams,         // 展开 requestSearchParams 的所有属性到 params 中
    };

    // 现在，你可以安全地遍历并删除属性，TypeScript 不会再报错 TS7053
    Object.keys(params).forEach(key => {
      // `params[key]` 现在是合法的，因为类型定义中包含了索引签名
      if (params[key] === null || params[key] === undefined || params[key] === '') {
        delete params[key]; // 直接从 params 对象中删除该属性
      }
    });
  
    const response = await request({
      method: 'GET',
      url: '/repair/request/list',
      params
    })
    
    assignedRequests.value = response.data.records
    requestPagination.total = response.data.total
    stats.pending = requestPagination.total
  } catch (error) {
    ElMessage.error('获取分配的维修单失败')
    console.error(error)
  }
}

const loadProcessRecords = async () => {
  try {
const params: {
  page: number; // pagination.current 通常是 number 类型
  size: number; // pagination.size 通常是 number 类型
  [key: string]: any; // ✨ 添加索引签名，允许通过字符串键访问，值为 any 类型
} = {
  page: pagination.current,
  size: pagination.size,
  ...searchParams, // 展开 searchParams 的所有属性
};

// 遍历 params 对象的所有键
Object.keys(params).forEach(key => {
  // `params[key]` 现在是类型安全的访问方式，不会再报错 TS7053
  // 检查值是否严格等于 null
  if (params[key] === null) {
    delete params[key]; // 如果是 null，则从 params 对象中删除该属性
  }
});

console.log(params); // 打印修改后的 params 对象

    const response = await request({
      method: 'GET',
      url: '/repair/process/list',
      params
    })
    
    processRecords.value = response.data.records
    pagination.total = response.data.total
    stats.completed = pagination.total
  } catch (error) {
    ElMessage.error('获取维修记录失败')
    console.error(error)
  }
}

const addPart = () => {
  processForm.parts.push({
    partName: '',
    quantity: 1,
    unitPrice: 0,
    fileList: []
  })
}

const removePart = (index: number) => {
  processForm.parts.splice(index, 1)
}

const resetForm = () => {
  processFormRef.value?.resetFields()
  processForm.parts = []
  fileList.value = []
  timeRange.value = []
  selectedRequest.value = null
  processForm.repairFileUrl = ''
}

const resetSearch = () => {
  searchParams.repairRequestId = null
  searchParams.repairerId = null
  loadProcessRecords()
}

const resetRequestSearch = () => {
  requestSearchParams.serialNumber = null
  requestSearchParams.applicantId = null
  loadAssignedRequests()
}

const handleFileExceed = (files: File[]) => {
  ElMessage.warning(`最多只能上传 ${files.length} 个文件`)
}


const uploadFileToServer = async (file: File) => {
  try {
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await request({
      method: 'POST',
      url: '/repair/request/uploadFile',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      transformRequest: [(data) => data]
    })
    console.log('文件上传响应:', response.data)
    return response // 返回完整响应数据
  } catch (error) {
    console.error('文件上传失败:', error)
    throw error
  }
}

const submitProcess = async () => {
  try {
    await processFormRef.value.validate()
    
    if (!timeRange.value || timeRange.value.length !== 2) {
      ElMessage.warning('请选择维修时段')
      return
    }

    if (!selectedRequest.value) {
      ElMessage.warning('请选择维修单')
      return
    }

    isSubmitting.value = true

    // 1. 上传维修文件（逐个上传）
    let repairFileUrls: string[] = []
    if (fileList.value.length > 0) {
      for (const fileItem of fileList.value) {
        try {
          const file = fileItem.raw || fileItem
          if (!(file instanceof File)) continue
          
          const response = await uploadFileToServer(file)
          console.log("uploadResponse:"+JSON.stringify(response, null, 2))
          repairFileUrls.push((response as any).message) // 使用返回的URL
        } catch (error) {
          console.error(`文件 ${fileItem.name} 上传失败:`, error)
          ElMessage.error(`文件 ${fileItem.name} 上传失败`)
        }
      }
    }

    // 2. 提交维修过程（先创建维修记录）
    const processResponse = await request({
      method: 'POST',
      url: '/repair/process/add',
      data: {
        repairRequestId: selectedRequest.value.id,
        repairerId: selectedRequest.value.assignedToId,
        startTime: timeRange.value[0].replace(' ', 'T'),
        endTime: timeRange.value[1].replace(' ', 'T'),
        repairNotes: processForm.repairNotes,
        repairFileUrl: repairFileUrls.join(','),
        totalCost: processForm.totalCost
      }
    })
    console.log("维修过程提交返回内容："+JSON.stringify(processResponse, null, 2))
    const repairProcessId = processResponse.data // 获取新创建的维修过程ID

    // 3. 上传配件文件并提交配件记录
    if (processForm.parts.length > 0) {
      const partPromises = processForm.parts.map(async (part) => {
        let partFileUrl = ''
        
        // 上传配件文件
        if (part.fileList?.length > 0) {
          try {
            const file = part.fileList[0].raw || part.fileList[0]
            if (file instanceof File) {
              const uploadResponse = await uploadFileToServer(file)
              partFileUrl = (uploadResponse as any).message
              console.log("uploadResponse:"+JSON.stringify(uploadResponse, null, 2))
            }
          } catch (error) {
            console.error('配件文件上传失败:', error)
            ElMessage.error(`配件 ${part.partName} 文件上传失败`)
            throw error
          }
        }

        // 提交配件记录
        try {
          await request({
            method: 'POST',
            url: '/repair/part/add',
            data: {
              repairProcessId: repairProcessId,
              partName: part.partName,
              quantity: part.quantity,
              unitPrice: part.unitPrice,
              partFileUrl: partFileUrl,
              status: '待审批' // 默认状态
            }
          })
        } catch (error) {
          console.error('配件提交失败:', error)
          ElMessage.error(`配件 ${part.partName} 提交失败`)
          throw error
        }
      })

      // 等待所有配件提交完成
      await Promise.all(partPromises)
    }

    ElMessage.success('维修记录提交成功')
    resetForm()
    loadProcessRecords()
    activeTab.value = 'history'
  } catch (error) {
    console.error('提交维修记录失败:', error)
    ElMessage.error(`提交维修记录失败: ${(error as any).message || '未知错误'}`)
  } finally {
    isSubmitting.value = false
  }
}

const showDetail = async (record: RepairProcess) => {
  try {
    currentRecord.value = record
    
    // 加载配件记录
    const partsResponse = await request({
      method: 'GET',
      url: '/repair/part/list',
      params: {
        page: 1,
        size: 100,
        repairProcessId: record.id
      }
    })
    
    currentParts.value = partsResponse.data.records
    detailDialog.visible = true
  } catch (error) {
    console.error('获取维修记录详情失败:', error)
    ElMessage.error('获取详情失败')
  }
}

const downloadFile = (url: string) => {
  if (!url) {
    ElMessage.warning('没有可下载的附件')
    return
  }
  
  const link = document.createElement('a')
  link.href = url
  link.target = '_blank'
  link.download = url.split('/').pop() || 'attachment'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const formatTimeRange = (start: string, end: string) => {
  return `${formatDateTime(start)} ~ ${formatDateTime(end)}`
}

const formatDateTime = (datetime: string) => {
  if (!datetime) return ''
  return new Date(datetime).toLocaleString()
}

const showRequestDialog = () => {
  requestDialog.visible = true
}

const handleRequestSelect = (row: RepairRequest) => {
  selectedRequest.value = row
  processForm.repairRequestId = row.id
  processForm.repairerId = row.assignedToId
  requestDialog.visible = false
}


const serialNumberOptions = ref<string[]>([])
const loadingSerialNumbers = ref(false)

// 获取设备序列号建议
const fetchSerialSuggestions = async (query: string) => {
  if (query) {
    loadingSerialNumbers.value = true
    try {
      const res = await request<string[]>({
        method: 'GET',
        url: '/device/serial/suggestions',
        params: { keyword: query }
      })
      serialNumberOptions.value = res.data
    } catch {
      ElMessage.error('获取设备序列号失败')
    } finally {
      loadingSerialNumbers.value = false
    }
  } else {
    serialNumberOptions.value = []
  }
}
const isImage = (file: any): boolean => {
  const name = file.name || ''
  return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(name)
}

const getFileUrl = (file: any): string => {
  return file.url || URL.createObjectURL(file.raw)
}
const isImageFile = (url: string): boolean => {
  return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url)
}
</script>
<style lang="scss" scoped>
.card-box {
  width: 100%;
  max-width: 100%;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.header {
  padding: 0.8rem 1.2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e6eaf0;
  background-color: #f7f9fc;
  
  h2 {
    font-weight: 600;
    font-size: 1.4rem;
    color: #333;
    user-select: none;
    margin: 0;
  }
  
  .stats {
    display: flex;
    gap: 8px;
    
    .el-tag {
      font-weight: 500;
      height: 28px;
      line-height: 28px;
      padding: 0 8px;
    }
  }
}

.filter-bar {
  padding: 0.8rem 1.2rem;
  background-color: #fafbfc;
  border-bottom: 1px solid #e6eaf0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  overflow-x: auto;
  white-space: nowrap;
  gap: 0.8rem;

  .el-form-item {
    margin-bottom: 0 !important;
    flex-shrink: 0;
    
    label {
      font-weight: 500;
      color: #606266;
      font-size: 0.9rem;
    }
  }

  .el-button {
    height: 32px;
    font-weight: 500;
    padding: 0 12px;
    flex-shrink: 0;
  }
}

.responsive-table-container {
  overflow-x: auto;
  background: #fff;
  padding: 0.8rem;
}

.custom-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 6px;
  font-size: 0.9rem;

  thead tr {
    background-color: #f5f7fa;
    color: #606266;
    font-weight: 600;
    user-select: none;
  }

  th, td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
  }

  th {
    font-size: 0.85rem;
  }

  tbody tr {
    background-color: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    transition: background-color 0.2s ease;

    &:hover {
      background-color: #f4f9ff;
    }
  }

  .truncate {
    max-width: 180px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .action-btns {
    display: flex;
    gap: 0.4rem;

    .el-button {
      padding: 0;
      width: 28px;
      height: 28px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
    }
  }
}

.no-attachment {
  color: #a9abb0;
  font-style: italic;
  user-select: none;
  font-size: 0.85rem;
}

.pagination-container {
  background-color: #fafbfc;
  padding: 0.8rem;
  border-top: 1px solid #e6eaf0;
  display: flex;
  justify-content: center;
}

.text-center {
  text-align: center;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

/* 表单样式 */
.form-wrapper {
  padding: 1rem;
}

.el-form {
  max-width: 1000px;
  margin: 0 auto;
  
  .el-form-item {
    margin-bottom: 1.5rem;
  }
}

.request-selector {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.request-info-display {
  flex: 1;
  padding: 1rem;
  background-color: #f8fafc;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  
  .request-info-row {
    display: flex;
    margin-bottom: 0.5rem;
    
    &.full-width {
      flex-direction: column;
    }
    
    .info-label {
      font-weight: 500;
      color: #606266;
      min-width: 80px;
    }
    
    .info-value {
      color: #303133;
      
      &.multiline {
        white-space: pre-line;
        line-height: 1.5;
      }
    }
  }
}

.parts-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.part-card {
  .part-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    
    .part-title {
      font-weight: 500;
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }
  }
  
  .part-details {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }
}

.file-list-preview,
.file-preview {
  margin-top: 0.5rem;
  padding: 0.5rem;
  background-color: #f5f7fa;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  
  .file-remove {
    color: #f56c6c;
    cursor: pointer;
    
    &:hover {
      color: #f78989;
    }
  }
}

.form-actions {
  margin-top: 2rem;
  display: flex;
  justify-content: center;
  gap: 1rem;
}

/* 详情对话框样式 */
.detail-content {
  .repair-notes {
    padding: 1rem;
    background-color: #f8fafc;
    border-radius: 4px;
    white-space: pre-line;
    line-height: 1.6;
  }
  
  .file-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0;
  }
  
  .no-files {
    color: #909399;
    font-style: italic;
  }
}

/* 响应式调整 */
@media (max-width: 992px) {
  .parts-container {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .header {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
  
  .filter-bar {
    flex-wrap: wrap;
    
    .el-form-item {
      width: 100%;
      margin-right: 0;
    }
  }
  
  .request-selector {
    flex-direction: column;
  }
  
  .part-details {
    grid-template-columns: 1fr !important;
  }
}
.file-preview-wrapper {
  margin-top: 8px;
  display: flex;
  align-items: center;
  position: relative;
}

.file-preview {
  position: relative;
  display: inline-block;
  cursor: pointer;
  width: 80px;
  height: 80px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f5f7fa;
  text-align: center;
  line-height: 80px;
  color: #606266;
  font-size: 12px;
  transition: border-color 0.3s ease;
}

.file-preview:hover {
  border-color: #409eff;
}

.preview-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.file-name {
  display: block;
  padding: 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-hover-preview {
  position: absolute;
  top: 0;
  z-index: 20;
  display: none;
  background: white;
  padding: 6px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  min-width: 120px;
  max-width: 200px;
  max-height: 200px;
  white-space: normal;
}

.left-preview {
  right: 100%; // 左侧显示
  margin-right: 10px;
}

.zoom-img {
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: contain;
}

.zoom-text {
  color: #303133;
  font-size: 14px;
  word-break: break-all;
}

.file-preview:hover .file-hover-preview {
  display: block;
}
.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 0.2s ease;
  margin-right: 4px;
  vertical-align: middle;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.thumbnail-download {
  display: inline-block;
  width: 0;
  height: 0;
  overflow: hidden;
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid #ddd;
}

.image-popover {
  padding: 0 !important;
  background-color: transparent !important;
  box-shadow: none !important;
  border: none !important;
}

.preview-img {
  width: 300px; // 放大图片
  height: auto;
  max-height: 400px;
  display: block;
  object-fit: contain;
  border: none;
  border-radius: 0;
  background: transparent;
}

.thumbnail-download {
  display: none; // 你也可以用按钮代替
}
</style>